package com.smart.community.region.controller;

import com.smart.community.commons.result.Result;
import com.smart.community.commons.annotation.ApiLog;
import com.smart.community.commons.enums.ApiLogOperationType;
import com.smart.community.commons.utils.SecurityUtils;
import com.smart.community.region.dto.BatchGenerateFeeRecordDTO;
import com.smart.community.region.dto.ShopFeeRecordDTO;
import com.smart.community.region.service.IShopFeeRecordService;
import com.smart.community.region.vo.ShopFeeRecordVO;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.util.List;
import java.util.Map;

/**
 * 店铺费用记录Controller
 * 遵循《Java后端SpringBoot代码开发规范_重构版.md》Controller层规范
 * 遵循《系统状态枚举权威标准声明.md》状态枚举规范
 * 
 * @author Wu.Liang
 * @version 1.0.0
 * @since 2025-01-30
 */
@Slf4j
@RestController
@RequestMapping("/region/shop-fee-records")
@Tag(name = "店铺费用记录管理", description = "店铺费用记录的增删改查和批量生成功能")
public class ShopFeeRecordController {
    
    @Autowired
    private IShopFeeRecordService shopFeeRecordService;
    
    /**
     * 分页查询费用记录
     * 遵循《Java后端SpringBoot代码开发规范_重构版.md》Controller层规范
     * 遵循《系统状态枚举权威标准声明.md》状态枚举规范
     * 
     * @param current 当前页
     * @param size 每页大小
     * @param shopId 店铺ID
     * @param feeType 费用类型
     * @param paymentStatus 支付状态
     * @param feeDateStart 费用日期开始
     * @param feeDateEnd 费用日期结束
     * @param dueDateStart 到期日期开始
     * @param dueDateEnd 到期日期结束
     * @return 分页结果
     */
    @ApiLog(logTitle = "分页查询费用记录", logType = 2, moduleName = "区域管理", operationType = ApiLogOperationType.QUERY)
    @GetMapping("/page")
    @Operation(summary = "分页查询费用记录", description = "根据条件分页查询费用记录列表")
    public Result<Object> getFeeRecordPage(
            @Parameter(description = "当前页", example = "1") @RequestParam(defaultValue = "1") Integer current,
            @Parameter(description = "每页大小", example = "10") @RequestParam(defaultValue = "10") Integer size,
            @Parameter(description = "店铺ID") @RequestParam(required = false) Long shopId,
            @Parameter(description = "费用类型") @RequestParam(required = false) String feeType,
            @Parameter(description = "支付状态") @RequestParam(required = false) Integer paymentStatus,
            @Parameter(description = "费用日期开始", example = "2025-01-01") @RequestParam(required = false) String feeDateStart,
            @Parameter(description = "费用日期结束", example = "2025-01-31") @RequestParam(required = false) String feeDateEnd,
            @Parameter(description = "到期日期开始", example = "2025-01-01") @RequestParam(required = false) String dueDateStart,
            @Parameter(description = "到期日期结束", example = "2025-01-31") @RequestParam(required = false) String dueDateEnd) throws Exception {
        
        // 参数校验
        if (current == null || current < 1) {
            return Result.fail("页码必须大于0");
        }
        if (size == null || size < 1 || size > 100) {
            return Result.fail("每页大小必须在1-100之间");
        }
        
        // 权限控制：获取当前用户信息
        Long currentUserId = SecurityUtils.getCurrentUserId();
        if (currentUserId == null) {
            return Result.fail("用户未登录");
        }
        
        // 业务参数校验
        validateFeeRecordQueryParams(shopId, feeType, paymentStatus, feeDateStart, feeDateEnd, dueDateStart, dueDateEnd);
        
        log.info("分页查询费用记录，当前页: {}, 每页大小: {}, 店铺ID: {}, 费用类型: {}, 支付状态: {}, 费用日期: {} - {}, 到期日期: {} - {}", 
                current, size, shopId, feeType, paymentStatus, feeDateStart, feeDateEnd, dueDateStart, dueDateEnd);
        
        Object result = shopFeeRecordService.getFeeRecordPage(current, size, shopId, feeType, paymentStatus, 
                feeDateStart, feeDateEnd, dueDateStart, dueDateEnd);
        
        log.info("分页查询费用记录成功，当前页: {}, 每页大小: {}", current, size);
        return Result.success("查询成功", result);
    }
    
    /**
     * 根据ID获取费用记录详情
     * 遵循《Java后端SpringBoot代码开发规范_重构版.md》Controller层规范
     * 
     * @param id 费用记录ID
     * @return 费用记录详情
     */
    @ApiLog(logTitle = "获取费用记录详情", logType = 2, moduleName = "区域管理", operationType = ApiLogOperationType.QUERY)
    @GetMapping("/{id}")
    @Operation(summary = "获取费用记录详情", description = "根据ID获取费用记录详细信息")
    public Result<ShopFeeRecordVO> getFeeRecordDetail(
            @Parameter(description = "费用记录ID", example = "1") @PathVariable Long id) throws Exception {
        
        // 参数校验
        if (id == null || id <= 0) {
            return Result.fail("费用记录ID必须大于0");
        }
        
        // 权限控制：获取当前用户信息
        Long currentUserId = SecurityUtils.getCurrentUserId();
        if (currentUserId == null) {
            return Result.fail("用户未登录");
        }
        
        log.info("获取费用记录详情，ID: {}", id);
        
        ShopFeeRecordVO result = shopFeeRecordService.getFeeRecordDetail(id);
        if (result == null) {
            return Result.fail("费用记录不存在");
        }
        
        log.info("获取费用记录详情成功，ID: {}", id);
        return Result.success("查询成功", result);
    }
    
    /**
     * 创建费用记录
     * 遵循《Java后端SpringBoot代码开发规范_重构版.md》Controller层规范
     * 
     * @param dto 费用记录DTO
     * @return 创建结果
     */
    @ApiLog(logTitle = "创建费用记录", logType = 2, moduleName = "区域管理", operationType = ApiLogOperationType.ADD)
    @PostMapping
    @Operation(summary = "创建费用记录", description = "创建新的费用记录")
    public Result<Long> createFeeRecord(@Valid @RequestBody ShopFeeRecordDTO dto) throws Exception {
        
        // 基础参数校验
        if (dto == null) {
            return Result.fail("费用记录信息不能为空");
        }
        
        // 权限控制：获取当前用户信息
        Long currentUserId = SecurityUtils.getCurrentUserId();
        if (currentUserId == null) {
            return Result.fail("用户未登录");
        }
        
        // 业务参数校验
        validateShopFeeRecordDTO(dto);
        
        log.info("创建费用记录，店铺ID: {}, 费用类型: {}, 费用金额: {}", 
                dto.getShopId(), dto.getFeeType(), dto.getFeeAmount());
        
        Long result = shopFeeRecordService.createFeeRecord(dto);
        
        log.info("创建费用记录成功，ID: {}", result);
        return Result.success("创建成功", result);
    }
    
    /**
     * 批量生成费用记录
     * 遵循《Java后端SpringBoot代码开发规范_重构版.md》Controller层规范
     * 
     * @param dto 批量生成DTO
     * @return 生成结果
     */
    @ApiLog(logTitle = "批量生成费用记录", logType = 2, moduleName = "区域管理", operationType = ApiLogOperationType.BATCH)
    @PostMapping("/batch-generate")
    @Operation(summary = "批量生成费用记录", description = "根据费用标准批量生成费用记录")
    public Result<Object> batchGenerateFeeRecords(@Valid @RequestBody BatchGenerateFeeRecordDTO dto) throws Exception {
        
        // 基础参数校验
        if (dto == null) {
            return Result.fail("批量生成参数不能为空");
        }
        
        // 权限控制：获取当前用户信息
        Long currentUserId = SecurityUtils.getCurrentUserId();
        if (currentUserId == null) {
            return Result.fail("用户未登录");
        }
        
        // 业务参数校验
        validateBatchGenerateDTO(dto);
        
        log.info("批量生成费用记录，店铺数量: {}, 费用类型: {}, 生成月份: {}, 生成方式: {}", 
                dto.getShopIds().size(), dto.getFeeType(), dto.getBatchMonth(), dto.getBatchMode());
        
        Object result = shopFeeRecordService.batchGenerateFeeRecords(dto);
        
        log.info("批量生成费用记录成功，店铺数量: {}", dto.getShopIds().size());
        return Result.success("批量生成成功", result);
    }
    
    /**
     * 更新费用记录
     * 遵循《Java后端SpringBoot代码开发规范_重构版.md》Controller层规范
     * 
     * @param id 费用记录ID
     * @param dto 费用记录DTO
     * @return 更新结果
     */
    @ApiLog(logTitle = "更新费用记录", logType = 2, moduleName = "区域管理", operationType = ApiLogOperationType.UPDATE)
    @PutMapping("/{id}")
    @Operation(summary = "更新费用记录", description = "更新费用记录信息")
    public Result<Boolean> updateFeeRecord(
            @Parameter(description = "费用记录ID", example = "1") @PathVariable Long id,
            @Valid @RequestBody ShopFeeRecordDTO dto) throws Exception {
        
        // 参数校验
        if (id == null || id <= 0) {
            return Result.fail("费用记录ID必须大于0");
        }
        if (dto == null) {
            return Result.fail("费用记录信息不能为空");
        }
        
        // 权限控制：获取当前用户信息
        Long currentUserId = SecurityUtils.getCurrentUserId();
        if (currentUserId == null) {
            return Result.fail("用户未登录");
        }
        
        // 业务参数校验
        validateShopFeeRecordDTO(dto);
        
        log.info("更新费用记录，ID: {}, 店铺ID: {}, 费用类型: {}", 
                id, dto.getShopId(), dto.getFeeType());
        
        Boolean result = shopFeeRecordService.updateFeeRecord(id, dto);
        
        log.info("更新费用记录成功，ID: {}", id);
        return Result.success("更新成功", result);
    }
    
    /**
     * 删除费用记录
     * 遵循《Java后端SpringBoot代码开发规范_重构版.md》Controller层规范
     * 
     * @param id 费用记录ID
     * @return 删除结果
     */
    @ApiLog(logTitle = "删除费用记录", logType = 2, moduleName = "区域管理", operationType = ApiLogOperationType.DELETE)
    @DeleteMapping("/{id}")
    @Operation(summary = "删除费用记录", description = "删除指定的费用记录")
    public Result<Boolean> deleteFeeRecord(
            @Parameter(description = "费用记录ID", example = "1") @PathVariable Long id) throws Exception {
        
        // 参数校验
        if (id == null || id <= 0) {
            return Result.fail("费用记录ID必须大于0");
        }
        
        // 权限控制：获取当前用户信息
        Long currentUserId = SecurityUtils.getCurrentUserId();
        if (currentUserId == null) {
            return Result.fail("用户未登录");
        }
        
        log.info("删除费用记录，ID: {}", id);
        
        Boolean result = shopFeeRecordService.deleteFeeRecord(id);
        
        log.info("删除费用记录成功，ID: {}", id);
        return Result.success("删除成功", result);
    }
    
    /**
     * 批量删除费用记录
     * 遵循《Java后端SpringBoot代码开发规范_重构版.md》Controller层规范
     * 
     * @param ids 费用记录ID列表
     * @return 删除结果
     */
    @ApiLog(logTitle = "批量删除费用记录", logType = 2, moduleName = "区域管理", operationType = ApiLogOperationType.BATCH)
    @DeleteMapping("/batch")
    @Operation(summary = "批量删除费用记录", description = "批量删除指定的费用记录")
    public Result<Boolean> batchDeleteFeeRecords(
            @Parameter(description = "费用记录ID列表") @RequestBody List<Long> ids) throws Exception {
        
        // 参数校验
        if (ids == null || ids.isEmpty()) {
            return Result.fail("费用记录ID列表不能为空");
        }
        for (Long id : ids) {
            if (id == null || id <= 0) {
                return Result.fail("费用记录ID必须大于0");
            }
        }
        
        // 权限控制：获取当前用户信息
        Long currentUserId = SecurityUtils.getCurrentUserId();
        if (currentUserId == null) {
            return Result.fail("用户未登录");
        }
        
        log.info("批量删除费用记录，数量: {}", ids.size());
        
        Boolean result = shopFeeRecordService.batchDeleteFeeRecords(ids);
        
        log.info("批量删除费用记录成功，数量: {}", ids.size());
        return Result.success("批量删除成功", result);
    }
    
    /**
     * 获取费用统计信息
     * 遵循《Java后端SpringBoot代码开发规范_重构版.md》Controller层规范
     * 
     * @param shopId 店铺ID
     * @param feeType 费用类型
     * @param paymentStatus 支付状态
     * @return 统计信息
     */
    @ApiLog(logTitle = "获取费用统计信息", logType = 2, moduleName = "区域管理", operationType = ApiLogOperationType.QUERY)
    @GetMapping("/statistics")
    @Operation(summary = "获取费用统计信息", description = "获取费用金额统计信息")
    public Result<Object> getFeeStatistics(
            @Parameter(description = "店铺ID") @RequestParam(required = false) Long shopId,
            @Parameter(description = "费用类型") @RequestParam(required = false) String feeType,
            @Parameter(description = "支付状态") @RequestParam(required = false) Integer paymentStatus) throws Exception {
        
        // 权限控制：获取当前用户信息
        Long currentUserId = SecurityUtils.getCurrentUserId();
        if (currentUserId == null) {
            return Result.fail("用户未登录");
        }
        
        // 业务参数校验
        validateFeeRecordQueryParams(shopId, feeType, paymentStatus, null, null, null, null);
        
        log.info("获取费用统计信息，店铺ID: {}, 费用类型: {}, 支付状态: {}", shopId, feeType, paymentStatus);
        
        Object result = shopFeeRecordService.getFeeStatistics(shopId, feeType, paymentStatus);
        
        log.info("获取费用统计信息成功");
        return Result.success("查询成功", result);
    }
    
    /**
     * 支付费用记录
     * 遵循《Java后端SpringBoot代码开发规范_重构版.md》Controller层规范
     * 
     * @param id 费用记录ID
     * @param paymentInfo 支付信息
     * @return 支付结果
     */
    @ApiLog(logTitle = "支付费用记录", logType = 2, moduleName = "区域管理", operationType = ApiLogOperationType.UPDATE)
    @PostMapping("/{id}/pay")
    @Operation(summary = "支付费用记录", description = "支付指定的费用记录")
    public Result<Boolean> payFeeRecord(
            @Parameter(description = "费用记录ID", example = "1") @PathVariable Long id,
            @RequestBody Map<String, Object> paymentInfo) throws Exception {
        
        // 参数校验
        if (id == null || id <= 0) {
            return Result.fail("费用记录ID必须大于0");
        }
        if (paymentInfo == null || paymentInfo.isEmpty()) {
            return Result.fail("支付信息不能为空");
        }
        
        // 权限控制：获取当前用户信息
        Long currentUserId = SecurityUtils.getCurrentUserId();
        if (currentUserId == null) {
            return Result.fail("用户未登录");
        }
        
        // 业务参数校验
        validatePaymentInfo(paymentInfo);
        
        log.info("支付费用记录，ID: {}, 支付信息: {}", id, paymentInfo);
        
        Boolean result = shopFeeRecordService.payFeeRecord(id, paymentInfo);
        
        log.info("支付费用记录成功，ID: {}", id);
        return Result.success("支付成功", result);
    }
    
    /**
     * 批量支付费用记录
     * 遵循《Java后端SpringBoot代码开发规范_重构版.md》Controller层规范
     * 
     * @param ids 费用记录ID列表
     * @param paymentInfo 支付信息
     * @return 支付结果
     */
    @ApiLog(logTitle = "批量支付费用记录", logType = 2, moduleName = "区域管理", operationType = ApiLogOperationType.BATCH)
    @PostMapping("/batch-pay")
    @Operation(summary = "批量支付费用记录", description = "批量支付指定的费用记录")
    public Result<Boolean> batchPayFeeRecords(
            @Parameter(description = "费用记录ID列表") @RequestBody Map<String, Object> requestData) {
        
        try {
            @SuppressWarnings("unchecked")
            List<Long> ids = (List<Long>) requestData.get("ids");
            @SuppressWarnings("unchecked")
            Map<String, Object> paymentInfo = (Map<String, Object>) requestData.get("paymentInfo");
            
            log.info("批量支付费用记录，数量: {}, 支付信息: {}", ids.size(), paymentInfo);
            
            Boolean result = shopFeeRecordService.batchPayFeeRecords(ids, paymentInfo);
            
            log.info("批量支付费用记录成功，数量: {}", ids.size());
            return Result.success(result);
            
        } catch (Exception e) {
            log.error("批量支付费用记录失败", e);
            return Result.error("批量支付费用记录失败: " + e.getMessage());
        }
    }
    
    /**
     * 催缴费用记录
     * 遵循《Java后端SpringBoot代码开发规范_重构版.md》Controller层规范
     * 
     * @param id 费用记录ID
     * @return 催缴结果
     */
    @ApiLog(logTitle = "催缴费用记录", logType = 2, moduleName = "区域管理", operationType = ApiLogOperationType.UPDATE)
    @PostMapping("/{id}/remind")
    @Operation(summary = "催缴费用记录", description = "催缴指定的费用记录")
    public Result<Boolean> remindFeeRecord(
            @Parameter(description = "费用记录ID", example = "1") @PathVariable Long id) {
        
        try {
            log.info("催缴费用记录，ID: {}", id);
            
            Boolean result = shopFeeRecordService.remindFeeRecord(id);
            
            log.info("催缴费用记录成功，ID: {}", id);
            return Result.success(result);
            
        } catch (Exception e) {
            log.error("催缴费用记录失败，ID: {}", id, e);
            return Result.error("催缴费用记录失败: " + e.getMessage());
        }
    }
    
    /**
     * 批量催缴费用记录
     * 遵循《Java后端SpringBoot代码开发规范_重构版.md》Controller层规范
     * 
     * @param ids 费用记录ID列表
     * @return 催缴结果
     */
    @ApiLog(logTitle = "批量催缴费用记录", logType = 2, moduleName = "区域管理", operationType = ApiLogOperationType.BATCH)
    @PostMapping("/batch-remind")
    @Operation(summary = "批量催缴费用记录", description = "批量催缴指定的费用记录")
    public Result<Boolean> batchRemindFeeRecords(
            @Parameter(description = "费用记录ID列表") @RequestBody List<Long> ids) {
        
        try {
            log.info("批量催缴费用记录，数量: {}", ids.size());
            
            Boolean result = shopFeeRecordService.batchRemindFeeRecords(ids);
            
            log.info("批量催缴费用记录成功，数量: {}", ids.size());
            return Result.success(result);
            
        } catch (Exception e) {
            log.error("批量催缴费用记录失败，数量: {}", ids.size(), e);
            return Result.error("批量催缴费用记录失败: " + e.getMessage());
        }
    }
    
    /**
     * 导出费用记录
     * 遵循《Java后端SpringBoot代码开发规范_重构版.md》Controller层规范
     * 
     * @param shopId 店铺ID
     * @param feeType 费用类型
     * @param paymentStatus 支付状态
     * @return 导出结果
     */
    @ApiLog(logTitle = "导出费用记录", logType = 2, moduleName = "区域管理", operationType = ApiLogOperationType.EXPORT)
    @PostMapping("/export")
    @Operation(summary = "导出费用记录", description = "导出费用记录数据")
    public Result<String> exportFeeRecords(
            @Parameter(description = "店铺ID") @RequestParam(required = false) Long shopId,
            @Parameter(description = "费用类型") @RequestParam(required = false) String feeType,
            @Parameter(description = "支付状态") @RequestParam(required = false) Integer paymentStatus) {
        
        try {
            log.info("导出费用记录，店铺ID: {}, 费用类型: {}, 支付状态: {}", shopId, feeType, paymentStatus);
            
            String result = shopFeeRecordService.exportFeeRecords(shopId, feeType, paymentStatus);
            
            log.info("导出费用记录成功");
            return Result.success(result);
            
        } catch (Exception e) {
            log.error("导出费用记录失败，店铺ID: {}, 费用类型: {}, 支付状态: {}", shopId, feeType, paymentStatus, e);
            return Result.error("导出费用记录失败: " + e.getMessage());
        }
    }
    
    /**
     * 费用记录查询参数业务规则验证
     * 遵循《Java后端SpringBoot代码开发规范_重构版.md》Controller层规范
     * 遵循《系统状态枚举权威标准声明.md》状态枚举规范
     */
    private void validateFeeRecordQueryParams(Long shopId, String feeType, Integer paymentStatus, 
            String feeDateStart, String feeDateEnd, String dueDateStart, String dueDateEnd) {
        // 店铺ID校验
        if (shopId != null && shopId <= 0) {
            throw new IllegalArgumentException("店铺ID必须大于0");
        }
        
        // 费用类型校验
        if (feeType != null && !feeType.trim().isEmpty()) {
            String[] validFeeTypes = {"PROPERTY", "WATER", "ELECTRIC", "GAS", "SANITATION"};
            boolean isValidType = false;
            for (String validType : validFeeTypes) {
                if (validType.equals(feeType)) {
                    isValidType = true;
                    break;
                }
            }
            if (!isValidType) {
                throw new IllegalArgumentException("费用类型必须是：PROPERTY、WATER、ELECTRIC、GAS、SANITATION之一");
            }
        }
        
        // 支付状态校验
        if (paymentStatus != null && (paymentStatus < 0 || paymentStatus > 2)) {
            throw new IllegalArgumentException("支付状态必须是：0-未支付，1-已支付，2-逾期");
        }
        
        // 费用日期校验
        if (feeDateStart != null && !feeDateStart.trim().isEmpty()) {
            try {
                java.time.LocalDate.parse(feeDateStart);
            } catch (Exception e) {
                throw new IllegalArgumentException("费用日期开始格式不正确，应为yyyy-MM-dd格式");
            }
        }
        
        if (feeDateEnd != null && !feeDateEnd.trim().isEmpty()) {
            try {
                java.time.LocalDate.parse(feeDateEnd);
            } catch (Exception e) {
                throw new IllegalArgumentException("费用日期结束格式不正确，应为yyyy-MM-dd格式");
            }
        }
        
        // 费用日期范围校验
        if (feeDateStart != null && !feeDateStart.trim().isEmpty() && 
            feeDateEnd != null && !feeDateEnd.trim().isEmpty()) {
            try {
                java.time.LocalDate start = java.time.LocalDate.parse(feeDateStart);
                java.time.LocalDate end = java.time.LocalDate.parse(feeDateEnd);
                if (start.isAfter(end)) {
                    throw new IllegalArgumentException("费用日期开始不能晚于结束日期");
                }
            } catch (Exception e) {
                if (e instanceof IllegalArgumentException && e.getMessage().contains("费用日期开始不能晚于结束日期")) {
                    throw e;
                }
                throw new IllegalArgumentException("费用日期范围格式不正确");
            }
        }
        
        // 到期日期校验
        if (dueDateStart != null && !dueDateStart.trim().isEmpty()) {
            try {
                java.time.LocalDate.parse(dueDateStart);
            } catch (Exception e) {
                throw new IllegalArgumentException("到期日期开始格式不正确，应为yyyy-MM-dd格式");
            }
        }
        
        if (dueDateEnd != null && !dueDateEnd.trim().isEmpty()) {
            try {
                java.time.LocalDate.parse(dueDateEnd);
            } catch (Exception e) {
                throw new IllegalArgumentException("到期日期结束格式不正确，应为yyyy-MM-dd格式");
            }
        }
        
        // 到期日期范围校验
        if (dueDateStart != null && !dueDateStart.trim().isEmpty() && 
            dueDateEnd != null && !dueDateEnd.trim().isEmpty()) {
            try {
                java.time.LocalDate start = java.time.LocalDate.parse(dueDateStart);
                java.time.LocalDate end = java.time.LocalDate.parse(dueDateEnd);
                if (start.isAfter(end)) {
                    throw new IllegalArgumentException("到期日期开始不能晚于结束日期");
                }
            } catch (Exception e) {
                if (e instanceof IllegalArgumentException && e.getMessage().contains("到期日期开始不能晚于结束日期")) {
                    throw e;
                }
                throw new IllegalArgumentException("到期日期范围格式不正确");
            }
        }
    }
    
    /**
     * 费用记录DTO业务规则验证
     * 遵循《Java后端SpringBoot代码开发规范_重构版.md》Controller层规范
     */
    private void validateShopFeeRecordDTO(ShopFeeRecordDTO dto) {
        // 店铺ID校验
        if (dto.getShopId() == null || dto.getShopId() <= 0) {
            throw new IllegalArgumentException("店铺ID必须大于0");
        }
        
        // 费用类型校验
        if (dto.getFeeType() == null || dto.getFeeType().trim().isEmpty()) {
            throw new IllegalArgumentException("费用类型不能为空");
        }
        String[] validFeeTypes = {"PROPERTY", "WATER", "ELECTRIC", "GAS", "SANITATION"};
        boolean isValidType = false;
        for (String validType : validFeeTypes) {
            if (validType.equals(dto.getFeeType())) {
                isValidType = true;
                break;
            }
        }
        if (!isValidType) {
            throw new IllegalArgumentException("费用类型必须是：PROPERTY、WATER、ELECTRIC、GAS、SANITATION之一");
        }
        
        // 费用金额校验
        if (dto.getFeeAmount() == null || dto.getFeeAmount().compareTo(java.math.BigDecimal.ZERO) <= 0) {
            throw new IllegalArgumentException("费用金额必须大于0");
        }
        
        // 费用期间校验
        if (dto.getFeePeriod() == null || dto.getFeePeriod().trim().isEmpty()) {
            throw new IllegalArgumentException("费用期间不能为空");
        }
        
        // 费用开始日期校验
        if (dto.getFeeStartDate() == null) {
            throw new IllegalArgumentException("费用开始日期不能为空");
        }
        
        // 费用结束日期校验
        if (dto.getFeeEndDate() == null) {
            throw new IllegalArgumentException("费用结束日期不能为空");
        }
        
        // 日期逻辑校验
        if (dto.getFeeStartDate().isAfter(dto.getFeeEndDate())) {
            throw new IllegalArgumentException("费用开始日期不能晚于结束日期");
        }
    }
    
    /**
     * 批量生成DTO业务规则验证
     * 遵循《Java后端SpringBoot代码开发规范_重构版.md》Controller层规范
     */
    private void validateBatchGenerateDTO(BatchGenerateFeeRecordDTO dto) {
        // 店铺ID列表校验
        if (dto.getShopIds() == null || dto.getShopIds().isEmpty()) {
            throw new IllegalArgumentException("店铺ID列表不能为空");
        }
        for (Long shopId : dto.getShopIds()) {
            if (shopId == null || shopId <= 0) {
                throw new IllegalArgumentException("店铺ID必须大于0");
            }
        }
        
        // 费用类型校验
        if (dto.getFeeType() == null || dto.getFeeType().trim().isEmpty()) {
            throw new IllegalArgumentException("费用类型不能为空");
        }
        String[] validFeeTypes = {"PROPERTY", "WATER", "ELECTRIC", "GAS", "SANITATION"};
        boolean isValidType = false;
        for (String validType : validFeeTypes) {
            if (validType.equals(dto.getFeeType())) {
                isValidType = true;
                break;
            }
        }
        if (!isValidType) {
            throw new IllegalArgumentException("费用类型必须是：PROPERTY、WATER、ELECTRIC、GAS、SANITATION之一");
        }
        
        // 生成月份校验
        if (dto.getBatchMonth() == null || dto.getBatchMonth().trim().isEmpty()) {
            throw new IllegalArgumentException("生成月份不能为空");
        }
        
        // 生成方式校验
        if (dto.getBatchMode() == null || dto.getBatchMode().trim().isEmpty()) {
            throw new IllegalArgumentException("生成方式不能为空");
        }
        // 支持前端发送的枚举值：STANDARD-按费用标准生成，CUSTOM-自定义金额
        // 同时兼容后端原有枚举值：AUTO-自动生成，MANUAL-手动生成
        String[] validModes = {"STANDARD", "CUSTOM", "AUTO", "MANUAL"};
        boolean isValidMode = false;
        for (String validMode : validModes) {
            if (validMode.equals(dto.getBatchMode())) {
                isValidMode = true;
                break;
            }
        }
        if (!isValidMode) {
            throw new IllegalArgumentException("生成方式必须是：STANDARD、CUSTOM、AUTO、MANUAL之一");
        }
    }
    
    /**
     * 支付信息业务规则验证
     * 遵循《Java后端SpringBoot代码开发规范_重构版.md》Controller层规范
     */
    private void validatePaymentInfo(Map<String, Object> paymentInfo) {
        // 支付方式校验
        if (!paymentInfo.containsKey("paymentMethod") || paymentInfo.get("paymentMethod") == null) {
            throw new IllegalArgumentException("支付方式不能为空");
        }
        String paymentMethod = paymentInfo.get("paymentMethod").toString();
        if (paymentMethod.trim().isEmpty()) {
            throw new IllegalArgumentException("支付方式不能为空");
        }
        
        // 支付日期校验
        if (!paymentInfo.containsKey("paymentDate") || paymentInfo.get("paymentDate") == null) {
            throw new IllegalArgumentException("支付日期不能为空");
        }
        String paymentDate = paymentInfo.get("paymentDate").toString();
        if (paymentDate.trim().isEmpty()) {
            throw new IllegalArgumentException("支付日期不能为空");
        }
        
        // 收据号校验（可选）
        if (paymentInfo.containsKey("receiptNumber") && paymentInfo.get("receiptNumber") != null) {
            String receiptNumber = paymentInfo.get("receiptNumber").toString();
            if (receiptNumber.trim().isEmpty()) {
                throw new IllegalArgumentException("收据号不能为空字符串");
            }
        }
    }
}
